package hku.cs.lunuo.cost;

import hku.cs.lunuo.Global;
import hku.cs.lunuo.rank.StmtResult;
import hku.cs.lunuo.rank.StmtResultUnit;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author xj One approach to evaluate the effectiveness of the
 *         fault-localization technique. This metric, we call expense is
 *         computed by the following equation. Expense = (rank of faulty
 *         statement) /(number of executable statements) *100%
 */


public class Expense {
	List<Error> error = new ArrayList<Error>();
	File errfile = null;
	
	public Expense(File err) {
		this.errfile = err;
	}

	public void getExpense(StmtResult result) {
		float expense = 0;
		try {
			getFaultyStmtLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (error.size() == 0) {
			System.out.println("Warning! You haven't set the error line.");
			return;
		}

		Iterator it = result.iterator();
		int lines = result.getSize();
		System.out.print("total_line:" + lines);
			while(it.hasNext()) {
				StmtResultUnit sru = (StmtResultUnit)it.next();
				Error r = new Error(sru.getKlassName(), sru.getLn());
				if (error.contains(r)) {
					expense = computeExpense(sru.getRank(), lines);
					// System.out.println("method=" + rankAlg.getName() +
					// " expense="
					// + expense + " rank=" + r.getRank() + " lines="
					// + lines);
					System.out.println(" "+Global.v().modelName+"_rank:"+sru.getRank()+" expense:"+expense);
					return;
				}
			}
			System.out.println("N ");
			// System.out.println("Can't find error line");
			// throw new IllegalStateException("  method:"+rankMethod);
	

	}

	public void getFaultyStmtLine() throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				new FileInputStream(errfile)));
		String line = reader.readLine();
		while (line != null) {
			String info = line.split("//")[1];
			if (info.split(" ").length == 2) {
				String klassName = info.split(" ")[0];
				String lines = info.split(" ")[1];
				for (String l : lines.split(",")) {
					String[] ls = l.split("~");
					if (ls.length == 1)
						error.add(new Error(klassName, Integer.parseInt(l)));
					else if (ls.length == 2)
						for (int i = Integer.parseInt(ls[0]); i < Integer
								.parseInt(ls[1]) + 1; i++)
							error.add(new Error(klassName, i));
				}
			}
			line = reader.readLine();
		}
		reader.close();
	}

	public float computeExpense(int rank, int total) {
		return (float) rank / total;
	}
}
